home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr29
/
keybuf20.zip
/
KEYBUF.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-05-28
|
7KB
|
182 lines
; Copyright (c) 1992-1993 by Vincenzo "Enzo" Romano
; All rights reserved.
; Vincenzo Romano appears on courtesy of Shq`n Soft (Pisa, ITALY)
title KEYBUF - Expands the keyboard buffer to 128 keystrokes
comment #
The use of this program implies the following disclaim.
LEGAL: THIS PROGRAM IS ABSOLUTELY FREE OF ANY CHARGE FOR SINGLE USERS.
FOR COMMERCIAL USES, PLEASE CONTACT THE AUTHOR.
THE AUTHOR WILL NOT BE RESPONSIBLE OF ANY KIND OF DAMAGE DUED
TO THE USE OF THIS PROGRAM.
THE USER WILL USE THIS PROGRAM AT HIS OWN RISK.
Problem: I use to work under UNIX and am accustomed to type command lines
before the program is ready to read it. This is not a problem in
UNIX but it's a big trouble under MS-DOG: MS-DOG has a 32 bytes
(16 keystrokes) long buffer, so I get a "beeeeep" and loose any
extra characters I type when my MS-DOG machine run outside its
keyboard buffer.
Solution: Write your own MS-DOG patch program or ... use KeyBuf!
Details: Every MS-DOG machine has a 16 keystrokes circular buffer in its
BIOS Variables Segment (BVS) at 0040:001E. In the BVS there're
4 variables too to manage this buffer: the head and the tail of
the circular buffer, the starting address and the address used
to check the wrap around of the first 2 pointers. By simply
changing these variables we can use another memory block as
keyboard buffer. Unluckyly these address are written as offsets
of the BVS so we cannot use any memory block but only those ones
we can reach as offsets relatively to the BVS (0040h). Let's do
some simple calculations. If our buffer is 256 bytes long, the
maximum offset we can use is 65535-256=65279 or 66303 as an
absolute memory address. What's the segment:offset format with
the lowest offset value to express such an addrress? It's easy:
it's (66303 div 16):(66303 mod 16) = 4143:15 = 102Fh:Fh.
Thus, our memory block segment is to be lower than 1030h to be
useful as a keyboard buffer.
If we run MS-DOG v5.00, we can load the MS-DOG itself in the HMA
and in some UMB leaving free our precious lower memory.
Anytime we run a program, MS-DOG prepends to it in memory a copy
of the variables environment. This copy is in higher memory if
we run the program high and is in lower memory if we run it low.
KeyBuf checks where it was loaded and uses its environment space
if it's running in low memory. Otherwise it allocates the buffer
in the lower available place.
Then it marks the buffer as owned by MS-DOG, sets the new values
in the BVS and then exits: KeyBuf is not a resident program but
allocates a memory block and modifies the BVS accordingly.
For more technical details, please read the code below.
I'd like to thank Ralph Brown for his "interrupts and memory map
compilation" a.k.a. INTERxx ( my version had xx=30 ): it was the
only useful documentation I used to write this little tool.
For bugs and suggestions please contact me via e-mail:
music@MILES.cnuce.cnr.it
#
BufLen equ 256 ; New keyboard buffer lenght
BVSeg equ 0040h ; BIOS variables segment (BVS)
MaxSeg equ 1030h ; Highest suitable segment (read comment)
DosOwn equ 0008h ; DOS memory block signature
MCBOwn equ 0001h ; Memory Control Bock owner field
StdBot equ 001Eh ; Usual buffer offset
BIOSVar segment byte at 0 ; BVS calculated relatively to segment 0000h
org 041Ah
Head dw ? ; Head pointer
Tail dw ? ; Tail pointer
org 0480h
Bot dw ? ; Starting offset of the buffer
Top dw ? ; Offset of the 1st word outside the buffer
BIOSVar ends
KeyBuf segment byte
assume CS:KeyBuf, SS:KeyBuf, DS:KeyBuf, ES:nothing
org 002Ch ; Program environment segment in the PSP
envseg dw ? ; structure.
org 0100h
main: ; Program (.COM) entry point
mov DX,offset greet
mov AH,09h
int 21h ; Greeting message printout
xor AX,AX ; First we see if KeyBuf was already loaded
mov ES,AX ; by inspecting the value of the BIOS variable
mov AX,ES:Bot ; used for the keyboard buffer.
cmp AX,StdBot
je first
mov DX,offset alrdy
mov AL,01h
jmp exit
first:
mov AH,48h ; Now we allocate a 256 bytes (128 2-bytes
mov BX,BufLen/16 ; keystrokes) memory block for our new buffer.
int 21h ; If the program environment segment is not
jnc allocok ; useful (too little or too high in memory)
mov AX,65535 ; we'll try to use this block.
allocok:
mov DX,AX ; Now we get our environment segment and
mov AX,envseg ; try to set its size to 256 bytes.
mov ES,AX
mov BX,BufLen/16
mov AH,4Ah
int 21h
jnc envok ; If the resize operation failed we set the
mov AX,65535 ; the environment segment as FFFFh so it will
jmp compare ; seem to be too high for the program.
envok:
mov AX,ES ; We choose the lower segment between the
compare:
cmp DX,AX ; environment and the allocated block and
ja axok ; put it in AX register.
mov AX,DX
axok:
cmp AX,MaxSeg ; Finally we check if the segment in AX is
jb segok ; lower enough in memory to be useful.
mov DX,offset toohi ; Because of the tricks with FFFFh, maybe
mov AL,02h ; that niether the environment segment nor
jmp exit ; the allocated block is suitable, so ...
segok:
mov DX,AX ; We set the buffer as owned by DOS, so
dec DX ; when we'll exit the program the memory
mov ES,DX ; block will remain "resident".
mov SI,MCBOwn
mov DX,DosOwn
mov ES:[SI],DX
mov CL,4 ; With simple calculations we translate
shl AX,CL ; our segment into an offset relatively
sub AX,BVSeg*16 ; to the BVS. (seg*16) = (BVSeg*16)+off
mov DX,AX ; --> off = (seg*16)-(BVSeg*16)
add DX,BufLen
push DS ; We'll use DS to address the BVS to be
xor CX,CX ; as fast as we can while in the disabled
mov DS,CX ; interrupts section below.
assume DS:BIOSVar
cli ; And now ... take the breath!
mov Head,AX ; While juggling with the BVS values
mov Tail,AX ; we have to avoid BIOS to modify those
mov Bot,AX ; values or we could get some incoherency.
mov Top,DX
sti ; Weew! You can breath normally, now!
assume DS:KeyBuf
pop DS
mov DX,offset allok ; Successful message printout and exit
mov AL,CL ; with ERRORLEVEL set to 0.
exit:
mov AH,09h
int 21h
mov AH,4Ch ; MS-DOG exit() service (AL = ERRORLEVEL)
int 21h
greet db 'KeyBuf 2.00 (c) 1992-1993 by Shq`n Soft',13,10,'KEYBUF : ','$'
alrdy db 'already installed',13,10,'$'
toohi db 'all memory below 1030:0 is busy',13,10,'$'
allok db 'successfully installed',13,10,'$'
KeyBuf ends
end main
; That's all folks!